<HTML>
<HEAD>
<TITLE> Scanning Routines in SPICELIB </TITLE>
</HEAD>

<BODY style="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255);">

<A NAME="top"></A>

<TABLE STYLE="text-align: left; margin-left: auto; margin-right: auto; width: 800px;" BORDER="0" CELLPADDING="5" CELLSPACING="2">
<TBODY>
<TR>
  <TD STYLE="background-color: rgb(153, 153, 153); vertical-align: middle; text-align: center;">
  <DIV ALIGN="right">
    <SMALL><SMALL><A HREF="index.html">Index Page</A></SMALL></SMALL>
  </DIV>
  <B>Scanning Routines in SPICELIB</B> </TD>
</TR>
<TR>
  <TD STYLE="vertical-align: top;">

<H2> Table of Contents
</H2>

<PRE>
   <A HREF="#Scanning Routines in SPICELIB">Scanning Routines in SPICELIB</A>
      <A HREF="#Abstract">Abstract</A>
      <A HREF="#Note on FORTRAN and C Versions">Note on FORTRAN and C Versions</A>
      <A HREF="#Introduction">Introduction</A>
      <A HREF="#Substring searches">Substring searches</A>
      <A HREF="#Character searches">Character searches</A>
      <A HREF="#Searching in reverse">Searching in reverse</A>
      <A HREF="#Notes">Notes</A>
      <A HREF="#Summary">Summary</A>

</PRE>

<HR SIZE=3 NOSHADE>

<BR><BR>
<A NAME="Scanning Routines in SPICELIB"></A>
<p align="right"><a href="#top"><small>Top</small></a></p>
<H1> Scanning Routines in SPICELIB
</H1><HR SIZE=3 NOSHADE><P><BR><BR><BR>
   Last revised on 2008 JAN 17 by B. V. Semenov.
<P>
 
<BR><BR>
<A NAME="Abstract"></A>
<p align="right"><a href="#top"><small>Top</small></a></p>
<H2> Abstract
</H2><HR ALIGN="LEFT" WIDTH=50% ><P><BR><BR>
   SPICELIB contains a set of subroutines that scan strings for characters
   or substrings in a variety of ways.
<P>
 
<BR><BR>
<A NAME="Note on FORTRAN and C Versions"></A>
<p align="right"><a href="#top"><small>Top</small></a></p>
<H2> Note on FORTRAN and C Versions
</H2><HR ALIGN="LEFT" WIDTH=50% ><P><BR><BR>
   This document covers the FORTRAN version of the interfaces of this
   subsystem. CSPICE provides f2c translated equivalents for all, and
   native C wrappers for some of them. If you wish to use the C versions of
   the interfaces described in this document, refer to the CSPICE Required
   Reading, <a href="../req/cspice.html">cspice.req</a>, for more information on naming conventions,
   locations, and usage of the f2c'ed routines and native C wrappers.
<P>
 
<BR><BR>
<A NAME="Introduction"></A>
<p align="right"><a href="#top"><small>Top</small></a></p>
<H2> Introduction
</H2><HR ALIGN="LEFT" WIDTH=50% ><P><BR><BR>
   Fortran offers a single intrinsic function for locating substrings
   within a string: INDEX. Given an arbitrary character string and a target
   string,
<P>
 
<PRE>
   LOC = INDEX ( STRING, TARGET )
</PRE>
   returns the smallest value such that the condition
<P>
 
<PRE>
   ( STRING(LOC : LOC+LEN(TARGET)-1)  .EQ.  TARGET )
</PRE>
   is true. For example, the value returned by
<P>
 
<PRE>
   INDEX ( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'GHI' )
</PRE>
   is seven. If the target string is contained nowhere in the original
   string, INDEX returns zero. Note that INDEX is not case sensitive, nor
   does it ignore leading or trailing blanks. Thus, all of the following
   references return zero.
<P>
 
<PRE>
   INDEX ( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', '123'  )
   INDEX ( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'ghi'  )
   INDEX ( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'GHI ' )
   INDEX ( 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', ' GHI' )
</PRE>
   In contrast, the True BASIC language (a dialect of BASIC) offers several
   similar, but more powerful, functions. Unlike the Fortran INDEX
   function, these extended functions allow you to
<P>
 
<UL>
<TT>--</TT> begin a search at any location within the string.
<BR><BR></UL>
<UL>
<TT>--</TT> search in two directions: forward (left to right), and reverse (right to
left).
<BR><BR></UL>
<UL>
<TT>--</TT> search for a multi-character substring; or for any character contained in
an arbitrary collection; or for any character NOT contained in an arbitrary
collection.
<BR><BR></UL>
   Using these functions to develop True BASIC programs convinced us that
   they should be available to Fortran programmers as well; so SPICELIB
   contains six integer functions, which are exactly equivalent to their
   True BASIC counterparts. The calling sequences are shown below.
<P>
 
<PRE>
   POS    ( STR, SUBSTR, START )
   CPOS   ( STR, CHARS,  START )
   NCPOS  ( STR, CHARS,  START )
   POSR   ( STR, SUBSTR, START )
   CPOSR  ( STR, CHARS,  START )
   NCPOSR ( STR, CHARS,  START )
</PRE>
<BR><BR>
<A NAME="Substring searches"></A>
<p align="right"><a href="#top"><small>Top</small></a></p>
<H2> Substring searches
</H2><HR ALIGN="LEFT" WIDTH=50% ><P><BR><BR>
   POS is just like INDEX, but takes a third argument: the location in the
   string at which the search is to begin. Beginning the search at location
   1 makes the two functions identical. The extra argument becomes
   important when you need to search a single string for several
   occurrences of a substring.
<P>
 
   Compare the following code fragments, which locate successive
   occurrences of the substring `//' within a string, first using INDEX:
<P>
 
<PRE>
   LOC = INDEX ( STRING, '//' )
 
   DO WHILE ( LOC .NE. 0 )
       .
       .
 
      IF ( LEN ( STRING )  .LE.  LOC + 2 ) THEN
         LOC = 0
      ELSE
         LOC = LOC + 2 + INDEX ( STRING(LOC+2: ), '//' )
      END IF
   END DO
</PRE>
   and then using POS:
<P>
 
<PRE>
   LOC = POS ( STRING, '//', 1 )
 
   DO WHILE ( LOC .NE. 0 )
       .
       .
 
      LOC = POS ( STRING, '//', LOC + 2 )
   END DO
</PRE>
<BR><BR>
<A NAME="Character searches"></A>
<p align="right"><a href="#top"><small>Top</small></a></p>
<H2> Character searches
</H2><HR ALIGN="LEFT" WIDTH=50% ><P><BR><BR>
   CPOS is different. Instead of looking for the complete target string, it
   looks for any one of the individual characters that make up the target
   string. For example,
<P>
 
<PRE>
   POS ( '(a (b c) (d e) () (f (g (h))))', '()', 1 )
                         ^
</PRE>
   returns location 16 (as indicated by the caret), because it is the first
   occurrence of the complete substring `()' within the string. However,
<P>
 
<PRE>
   CPOS ( '(a (b c) (d e) () (f (g (h))))', '()', 1 )
           ^
</PRE>
   returns location 1, since it is the first location at which either of
   the characters ( `(' or `)' ) appear. Thus, POS treats the target string
   as an ordered sequence of characters, while CPOS treats the target
   string as an unordered collection of individual characters.
<P>
 
   A third function, NCPOS, looks for characters that are NOT included in
   the collection. Thus,
<P>
 
<PRE>
   NCPOS ( '(a (b c) (d e) () (f (g (h))))', '()', 1 )
             ^
</PRE>
   returns location 2, since it is the first location at which something
   other than one of the characters in the target string appears.
<P>
 
   This is useful for finding unwanted characters. For example, suppose you
   wish to replace each character in a string that is not part of the
   Fortran standard character set,
<P>
 
<PRE>
   CHARACTER*(*)        LET
   PARAMETER          ( LET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' )
 
   CHARACTER*(*)        DIG
   PARAMETER          ( DIG = '0123456789' )
 
   CHARACTER*(*)        SPEC
   PARAMETER          ( SPEC = ' =+-*/(),.$'':' )
</PRE>
   with a space character, to prevent compilation problems. The following
   code fragment does the job.
<P>
 
<PRE>
   LOC = NCPOS ( STRING, LET // DIG // SPEC, 1 )
 
   DO WHILE ( LOC .GT. 0 )
      STRING(LOC:LOC) = ' '
 
      LOC = NCPOS ( STRING, LET // DIG // SPEC, LOC )
   END DO
</PRE>
   Note that characters do not need to be in any special order, so all of
   the following are equivalent.
<P>
 
<PRE>
   NCPOS ( STR, 'ABC', BEGIN )
   NCPOS ( STR, 'ACB', BEGIN )
   NCPOS ( STR, 'BAC', BEGIN )
   NCPOS ( STR, 'BCA', BEGIN )
   NCPOS ( STR, 'CAB', BEGIN )
   NCPOS ( STR, 'CBA', BEGIN )
</PRE>
<BR><BR>
<A NAME="Searching in reverse"></A>
<p align="right"><a href="#top"><small>Top</small></a></p>
<H2> Searching in reverse
</H2><HR ALIGN="LEFT" WIDTH=50% ><P><BR><BR>
   POS, CPOS, and NCPOS find the first occurrence of something at or after
   some position, searching forward (from left to right). Each of these
   routines has a counterpart, which searches in reverse (frome right to
   left). For example, where
<P>
 
<PRE>
   POS ( 'do re mi fa so la ti do', 'do', 10 )
                               ^
</PRE>
   finds the second occurrence of the target string (at location 22),
<P>
 
<PRE>
   POSR ( 'do re mi fa so la ti do', 'do', 10 )
           ^
</PRE>
   finds the first occurrence (at location 1).
<P>
 
<BR><BR>
<A NAME="Notes"></A>
<p align="right"><a href="#top"><small>Top</small></a></p>
<H2> Notes
</H2><HR ALIGN="LEFT" WIDTH=50% ><P><BR><BR>
   Like INDEX, these functions
<P>
 
<UL>
<TT>--</TT> are not case-sensitive;
<BR><BR></UL>
<UL>
<TT>--</TT> do not ignore leading or trailing spaces; and
<BR><BR></UL>
<UL>
<TT>--</TT> indicate an unsuccessful search by returning zero.
<BR><BR></UL>
   Furthermore, you are not required to begin the search within the actual
   bounds of the string.
<P>
 
<UL>
<TT>--</TT> If START is zero or negative, a forward search begins at 1 (since this
location follows START), while a reverse search terminates immediately
(since there is nothing to search before START).
<BR><BR></UL>
<UL>
<TT>--</TT> If START is greater than the length of the string, a forward search
terminates immediately (since there is nothing to search after START),
while a reverse search begins at the end of the string (since this location
precedes START).
<BR><BR></UL>
<BR><BR>
<A NAME="Summary"></A>
<p align="right"><a href="#top"><small>Top</small></a></p>
<H2> Summary
</H2><HR ALIGN="LEFT" WIDTH=50% ><P><BR><BR>
   The following table summarizes the scanning routines in SPICELIB.
<P>
 
<B>POS</B>         Forward   Substring.
</PRE>
<BR>
<B>CPOS</B>        Forward   Character in collection.
</PRE>
<BR>
<B>NCPOS</B>       Forward   Character NOT in collection.
</PRE>
<BR>
<B>POSR</B>        Reverse   Substring.
</PRE>
<BR>
<B>CPOSR</B>       Reverse   Character in collection.
</PRE>
<BR>
<B>NCPOSR</B>      Reverse   Character NOT in collection.
</PRE>
<BR>
<PRE>
</PRE>

</TD>
</TR>
</TBODY>
</TABLE>

</BODY>

</HTML>
